<template>
  <div class="model-training">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">模型训练</h1>
        <p class="page-description">配置和启动机器学习模型训练，监控训练进度和性能</p>
      </div>
      <div class="header-actions">
        <el-button 
          type="primary" 
          @click="startTraining"
          :disabled="isTraining"
          :loading="isTraining"
        >
          <el-icon><VideoPlay /></el-icon>
          {{ isTraining ? '训练中...' : '开始训练' }}
        </el-button>
        <el-button 
          v-if="isTraining"
          type="danger" 
          @click="stopTraining"
        >
          <el-icon><VideoPause /></el-icon>
          停止训练
        </el-button>
      </div>
    </div>

    <!-- 训练配置 -->
    <div class="training-config">
      <el-card>
        <template #header>
          <span>训练配置</span>
        </template>
        <el-form 
          ref="configFormRef" 
          :model="trainingConfig" 
          :rules="configRules" 
          label-width="120px"
          :disabled="isTraining"
        >
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="模型名称" prop="modelName">
                <el-input v-model="trainingConfig.modelName" placeholder="请输入模型名称" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="模型类型" prop="modelType">
                <el-select
                  v-model="trainingConfig.modelType"
                  placeholder="选择模型类型"
                  @change="handleModelTypeChange"
                >
                  <el-option
                    v-for="type in businessModelTypes"
                    :key="type.value"
                    :label="type.label"
                    :value="type.value"
                  >
                    <div style="display: flex; justify-content: space-between; align-items: center;">
                      <span>{{ type.label }}</span>
                      <el-tag size="small" type="info">{{ type.category }}</el-tag>
                    </div>
                    <div style="font-size: 12px; color: #999; margin-top: 2px;">
                      {{ type.description }}
                    </div>
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="算法选择" prop="algorithm">
                <el-select
                  v-model="trainingConfig.algorithm"
                  placeholder="选择算法"
                  :disabled="!trainingConfig.modelType"
                  @change="handleAlgorithmChange"
                >
                  <el-option
                    v-for="algo in availableAlgorithms"
                    :key="algo.value"
                    :label="algo.label"
                    :value="algo.value"
                  >
                    <div style="display: flex; justify-content: space-between; align-items: center;">
                      <span>{{ algo.label }}</span>
                      <div>
                        <el-tag size="small" :type="getComplexityType(algo.complexity)">
                          {{ getComplexityLabel(algo.complexity) }}
                        </el-tag>
                        <el-tag size="small" type="success" style="margin-left: 4px;">
                          {{ algo.accuracy }}
                        </el-tag>
                      </div>
                    </div>
                    <div style="font-size: 12px; color: #999; margin-top: 2px;">
                      {{ algo.description }} · 训练时间: {{ algo.training_time }}
                    </div>
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="数据集" prop="dataset">
                <el-select
                  v-model="trainingConfig.dataset"
                  placeholder="选择数据集"
                  :disabled="!trainingConfig.modelType"
                >
                  <el-option
                    v-for="dataset in availableDatasets"
                    :key="dataset.value"
                    :label="dataset.label"
                    :value="dataset.value"
                  >
                    <div>{{ dataset.label }}</div>
                    <div style="font-size: 12px; color: #999; margin-top: 2px;">
                      {{ dataset.description }}
                    </div>
                    <div style="font-size: 11px; color: #666; margin-top: 2px;">
                      特征: {{ dataset.features ? dataset.features.join(', ') : '自动生成' }}
                    </div>
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 基础训练参数 -->
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="训练轮数" prop="epochs">
                <el-input-number
                  v-model="trainingConfig.epochs"
                  :min="1"
                  :max="1000"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="测试集比例" prop="testSize">
                <el-input-number
                  v-model="trainingConfig.testSize"
                  :min="0.1"
                  :max="0.5"
                  :step="0.05"
                  :precision="2"
                  style="width: 100%"
                />
                <div style="font-size: 12px; color: #999; margin-top: 4px;">
                  训练集: {{ ((1 - trainingConfig.testSize) * 100).toFixed(0) }}% |
                  测试集: {{ (trainingConfig.testSize * 100).toFixed(0) }}%
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="随机种子" prop="randomState">
                <el-input-number
                  v-model="trainingConfig.randomState"
                  :min="1"
                  :max="9999"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 自动调参配置 -->
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="自动调参" prop="enableHyperparamTuning">
                <el-switch
                  v-model="trainingConfig.enableHyperparamTuning"
                  active-text="启用"
                  inactive-text="禁用"
                />
                <div style="font-size: 12px; color: #999; margin-top: 4px;">
                  启用后将自动搜索最优参数组合
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="调参策略" prop="tuningStrategy" v-if="trainingConfig.enableHyperparamTuning">
                <el-select v-model="trainingConfig.tuningStrategy" style="width: 100%">
                  <el-option label="网格搜索 (精确但慢)" value="grid_search" />
                  <el-option label="随机搜索 (快速)" value="random_search" />
                  <el-option label="贝叶斯优化 (智能)" value="bayesian_optimization" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 调参参数 -->
          <el-row :gutter="20" v-if="trainingConfig.enableHyperparamTuning">
            <el-col :span="12">
              <el-form-item label="搜索迭代次数" prop="tuningIterations">
                <el-input-number
                  v-model="trainingConfig.tuningIterations"
                  :min="5"
                  :max="100"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="交叉验证折数" prop="cvFolds">
                <el-input-number
                  v-model="trainingConfig.cvFolds"
                  :min="3"
                  :max="10"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="模型描述">
            <el-input 
              v-model="trainingConfig.description" 
              type="textarea" 
              :rows="3"
              placeholder="请输入模型描述"
            />
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 训练进度 -->
    <div v-if="isTraining || trainingHistory.length > 0" class="training-progress">
      <el-card>
        <template #header>
          <span>训练进度</span>
        </template>
        
        <div v-if="isTraining" class="current-training">
          <!-- 当前操作状态 -->
          <div class="current-operation">
            <div class="operation-info">
              <el-icon class="spinning"><Loading /></el-icon>
              <span class="operation-text">{{ currentOperation }}</span>
            </div>
            <div class="operation-details">
              <span v-if="currentStep">{{ currentStep }}</span>
            </div>
          </div>

          <div class="progress-info">
            <div class="progress-stats">
              <div class="stat-item">
                <span class="label">训练阶段：</span>
                <span class="value">{{ trainingPhase }}</span>
              </div>
              <div class="stat-item">
                <span class="label">当前进度：</span>
                <span class="value">{{ currentEpoch }}%</span>
              </div>
              <div class="stat-item">
                <span class="label">调优迭代：</span>
                <span class="value">{{ tuningIteration }} / {{ maxTuningIterations }}</span>
              </div>
              <div class="stat-item">
                <span class="label">已用时间：</span>
                <span class="value">{{ elapsedTime }}</span>
              </div>
              <div class="stat-item">
                <span class="label">预计剩余：</span>
                <span class="value">{{ estimatedTime }}</span>
              </div>
              <div class="stat-item">
                <span class="label">当前最佳F1：</span>
                <span class="value">{{ currentBestF1 }}</span>
              </div>
            </div>
            <el-progress
              :percentage="currentEpoch"
              :stroke-width="12"
              :show-text="true"
              :format="(percentage) => `${percentage}%`"
            />
          </div>

          <div class="training-metrics">
            <el-row :gutter="20">
              <el-col :span="6" v-for="metric in currentMetrics" :key="metric.key">
                <div class="metric-card">
                  <div class="metric-label">{{ metric.label }}</div>
                  <div class="metric-value">{{ metric.value }}</div>
                </div>
              </el-col>
            </el-row>
          </div>
        </div>

        <!-- 训练历史图表 -->
        <div class="training-charts">
          <el-row :gutter="20">
            <el-col :span="12">
              <div class="chart-container" ref="lossChartRef"></div>
            </el-col>
            <el-col :span="12">
              <div class="chart-container" ref="accuracyChartRef"></div>
            </el-col>
          </el-row>
        </div>
      </el-card>
    </div>

    <!-- 训练日志 -->
    <div v-if="trainingLogs.length > 0" class="training-logs">
      <el-card>
        <template #header>
          <div class="logs-header">
            <span>训练日志</span>
            <el-button size="small" @click="clearLogs">
              <el-icon><Delete /></el-icon>
              清空日志
            </el-button>
          </div>
        </template>
        
        <div class="logs-container">
          <div 
            v-for="(log, index) in trainingLogs" 
            :key="index"
            class="log-item"
            :class="getLogClass(log.type)"
          >
            <span class="log-time">{{ log.timestamp }}</span>
            <span class="log-message">{{ log.message }}</span>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 训练完成结果 -->
    <div v-if="trainingResult" class="training-result">
      <el-card>
        <template #header>
          <span>训练结果</span>
        </template>
        
        <el-result
          :icon="trainingResult.success ? 'success' : 'error'"
          :title="trainingResult.title"
          :sub-title="trainingResult.message"
        >
          <template #extra>
            <el-button type="primary" @click="viewModel">查看模型</el-button>
            <el-button @click="evaluateModel">评估模型</el-button>
            <el-button @click="resetTraining">重新训练</el-button>
          </template>
        </el-result>

        <div v-if="trainingResult.success" class="final-metrics">
          <h4>最终指标</h4>
          <el-descriptions :column="3" border>
            <el-descriptions-item label="最终损失">{{ trainingResult.finalLoss }}</el-descriptions-item>
            <el-descriptions-item label="最终准确率">{{ trainingResult.finalAccuracy }}%</el-descriptions-item>
            <el-descriptions-item label="训练时长">{{ trainingResult.duration }}</el-descriptions-item>
            <el-descriptions-item label="模型大小">{{ trainingResult.modelSize }}</el-descriptions-item>
            <el-descriptions-item label="参数数量">{{ trainingResult.parameters }}</el-descriptions-item>
            <el-descriptions-item label="验证分数">{{ trainingResult.validationScore }}</el-descriptions-item>
          </el-descriptions>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import {
  VideoPlay, VideoPause, Delete, Loading
} from '@element-plus/icons-vue'
import {
  createModel,
  startTraining as startModelTraining,
  getTrainingStatus,
  stopTraining as stopModelTraining
} from '@/api/models'

// 路由实例
const route = useRoute()
const router = useRouter()

// 响应式数据
const isTraining = ref(false)
const currentEpoch = ref(0)
const configFormRef = ref(null)
const currentModelId = ref(null)
const statusCheckInterval = ref(null)

// 详细训练状态
const currentOperation = ref('准备开始训练...')
const currentStep = ref('')
const trainingPhase = ref('初始化')
const tuningIteration = ref(0)
const maxTuningIterations = ref(0)
const elapsedTime = ref('00:00')
const estimatedTime = ref('计算中...')
const currentBestF1 = ref('N/A')
const trainingStartTime = ref(null)

// 业务模型类型
const businessModelTypes = ref([
  {
    value: 'churn_prediction',
    label: '用户流失预测',
    category: '预测分析',
    description: '预测用户是否会流失，帮助制定挽留策略',
    business_value: '通过预测用户流失，提前采取挽留措施，降低客户流失率，提高客户生命周期价值'
  },
  {
    value: 'purchase_prediction',
    label: '购买意向预测',
    category: '预测分析',
    description: '预测用户的购买意向，优化营销策略',
    business_value: '精准识别高购买意向用户，提高营销转化率，降低营销成本'
  },
  {
    value: 'recommendation',
    label: '商品推荐系统',
    category: '推荐系统',
    description: '为用户推荐个性化商品，提升购买体验',
    business_value: '提供个性化推荐，提高用户满意度和购买转化率，增加客单价'
  },
  {
    value: 'user_segmentation',
    label: '用户行为分群',
    category: '聚类分析',
    description: '根据用户行为特征进行分群，制定差异化策略',
    business_value: '深入了解用户群体特征，制定精准的营销策略和产品策略'
  }
])

// 可用算法
const availableAlgorithms = ref([])

// 可用数据集
const availableDatasets = ref([])

// 算法配置映射
const algorithmConfigs = {
  'churn_prediction': [
    {
      value: 'xgboost',
      label: 'XGBoost',
      complexity: 'medium',
      accuracy: '高精度',
      training_time: '中等',
      description: '梯度提升决策树，适合结构化数据'
    },
    {
      value: 'random_forest',
      label: '随机森林',
      complexity: 'low',
      accuracy: '高精度',
      training_time: '快速',
      description: '集成学习算法，稳定性好'
    },
    {
      value: 'logistic_regression',
      label: '逻辑回归',
      complexity: 'low',
      accuracy: '中等',
      training_time: '很快',
      description: '经典分类算法，可解释性强'
    },
    {
      value: 'neural_network',
      label: '神经网络',
      complexity: 'high',
      accuracy: '高精度',
      training_time: '较慢',
      description: '深度学习模型，适合复杂模式'
    }
  ],
  'purchase_prediction': [
    {
      value: 'xgboost',
      label: 'XGBoost',
      complexity: 'medium',
      accuracy: '高精度',
      training_time: '中等',
      description: '梯度提升决策树，适合结构化数据'
    },
    {
      value: 'random_forest',
      label: '随机森林',
      complexity: 'low',
      accuracy: '高精度',
      training_time: '快速',
      description: '集成学习算法，稳定性好'
    },
    {
      value: 'neural_network',
      label: '神经网络',
      complexity: 'high',
      accuracy: '高精度',
      training_time: '较慢',
      description: '深度学习模型，适合复杂模式'
    }
  ],
  'recommendation': [
    {
      value: 'collaborative_filtering',
      label: '协同过滤',
      complexity: 'medium',
      accuracy: '中等',
      training_time: '中等',
      description: '基于用户行为相似性推荐'
    },
    {
      value: 'matrix_factorization',
      label: '矩阵分解',
      complexity: 'high',
      accuracy: '高精度',
      training_time: '较慢',
      description: '通过矩阵分解发现潜在特征'
    },
    {
      value: 'content_based',
      label: '基于内容',
      complexity: 'low',
      accuracy: '中等',
      training_time: '快速',
      description: '基于商品特征相似性推荐'
    }
  ],
  'user_segmentation': [
    {
      value: 'kmeans',
      label: 'K-Means',
      complexity: 'low',
      accuracy: '中等',
      training_time: '快速',
      description: '经典聚类算法，需要预设聚类数'
    },
    {
      value: 'dbscan',
      label: 'DBSCAN',
      complexity: 'medium',
      accuracy: '中等',
      training_time: '中等',
      description: '密度聚类，自动发现聚类数'
    },
    {
      value: 'hierarchical',
      label: '层次聚类',
      complexity: 'medium',
      accuracy: '中等',
      training_time: '较慢',
      description: '构建聚类层次结构'
    }
  ]
}

// 数据集配置映射
const datasetConfigs = {
  'churn_prediction': [
    {
      value: 'user_behavior',
      label: '用户行为数据',
      description: '包含用户活跃度、消费习惯等特征',
      features: ['年龄', '消费金额', '活跃天数', '订单数量', '客服咨询']
    }
  ],
  'purchase_prediction': [
    {
      value: 'user_interaction',
      label: '用户交互数据',
      description: '包含浏览、点击、收藏等行为数据',
      features: ['浏览时长', '页面访问', '购物车', '收藏数', '搜索记录']
    }
  ],
  'recommendation': [
    {
      value: 'user_item_ratings',
      label: '用户商品评分',
      description: '用户对商品的评分和交互数据',
      features: ['用户ID', '商品ID', '评分', '时间戳']
    },
    {
      value: 'user_item_interactions',
      label: '用户商品交互',
      description: '用户与商品的交互行为数据',
      features: ['用户ID', '商品ID', '交互类型', '评分', '时间戳']
    }
  ],
  'user_segmentation': [
    {
      value: 'rfm_data',
      label: 'RFM分析数据',
      description: '基于最近购买、频率、金额的用户数据',
      features: ['最近购买', '购买频率', '消费金额', '客户价值', '活跃度']
    }
  ]
}

// 图表引用
const lossChartRef = ref(null)
const accuracyChartRef = ref(null)

// 训练配置
const trainingConfig = reactive({
  modelName: '',
  modelType: '',
  algorithm: '',
  dataset: '',
  epochs: 30,  // 适中的轮次
  testSize: 0.25,  // 25%测试集，平衡训练和验证
  randomState: 42,
  enableHyperparamTuning: true,  // 启用调优
  tuningStrategy: 'random_search',  // 随机搜索
  tuningIterations: 20,  // 20次迭代，更充分的调优
  cvFolds: 4,  // 4折交叉验证，更好的模型评估
  trainingMode: 'balanced',  // 默认平衡模式
  description: '',
  training_params: {}
})

// 表单验证规则
const configRules = {
  modelName: [
    { required: true, message: '请输入模型名称', trigger: 'blur' },
    { min: 2, max: 50, message: '模型名称长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  modelType: [
    { required: true, message: '请选择模型类型', trigger: 'change' }
  ],
  algorithm: [
    { required: true, message: '请选择算法', trigger: 'change' }
  ],
  dataset: [
    { required: true, message: '请选择数据集', trigger: 'change' }
  ],
  description: [
    { required: true, message: '请输入模型描述', trigger: 'blur' },
    { min: 10, max: 200, message: '描述长度在 10 到 200 个字符', trigger: 'blur' }
  ]
}



// 训练进度
const overallProgress = computed(() => {
  if (!isTraining.value || trainingConfig.epochs === 0) return 0
  return Math.round((currentEpoch.value / trainingConfig.epochs) * 100)
})

const estimatedTime = computed(() => {
  if (!isTraining.value) return '00:00:00'
  const remaining = trainingConfig.epochs - currentEpoch.value
  const avgTimePerEpoch = 30 // 假设每轮30秒
  const totalSeconds = remaining * avgTimePerEpoch
  
  const hours = Math.floor(totalSeconds / 3600)
  const minutes = Math.floor((totalSeconds % 3600) / 60)
  const seconds = totalSeconds % 60
  
  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
})

// 当前指标
const currentMetrics = ref([
  { key: 'loss', label: '损失', value: '0.0000' },
  { key: 'accuracy', label: '准确率', value: '0.00%' },
  { key: 'val_loss', label: '验证损失', value: '0.0000' },
  { key: 'val_accuracy', label: '验证准确率', value: '0.00%' }
])

// 训练历史
const trainingHistory = ref([])

// 训练日志
const trainingLogs = ref([])

// 训练结果
const trainingResult = ref(null)

// 定时器
let trainingTimer = null

// 方法
const startTraining = async () => {
  try {
    await configFormRef.value.validate()

    // 初始化训练状态
    isTraining.value = true
    currentEpoch.value = 0
    trainingHistory.value = []
    trainingLogs.value = []
    trainingResult.value = null

    // 初始化详细状态
    currentOperation.value = '正在创建模型...'
    currentStep.value = '准备训练环境和配置'
    trainingPhase.value = '初始化'
    tuningIteration.value = 0
    maxTuningIterations.value = trainingConfig.tuningIterations
    elapsedTime.value = '00:00'
    estimatedTime.value = '计算中...'
    currentBestF1.value = 'N/A'
    trainingStartTime.value = Date.now()

    addLog('info', `🚀 开始训练模型: ${trainingConfig.modelName}`)
    addLog('info', `📊 算法: ${trainingConfig.algorithm}, 类型: ${trainingConfig.modelType}`)
    addLog('info', `⚙️ 调优策略: ${trainingConfig.tuningStrategy}, 迭代次数: ${trainingConfig.tuningIterations}`)

    // 创建模型
    const modelData = {
      name: trainingConfig.modelName,
      model_type: trainingConfig.modelType,
      algorithm: trainingConfig.algorithm,
      dataset: trainingConfig.dataset,
      description: trainingConfig.description,
      training_params: {
        ...trainingConfig.training_params,
        // 添加训练配置参数
        epochs: trainingConfig.epochs,
        test_size: trainingConfig.testSize,
        random_state: trainingConfig.randomState,
        enable_hyperparameter_tuning: trainingConfig.enableHyperparamTuning,
        tuning_strategy: trainingConfig.tuningStrategy,
        tuning_iterations: trainingConfig.tuningIterations,
        cv_folds: trainingConfig.cvFolds
      }
    }

    const createResponse = await createModel(modelData)
    if (!createResponse.success) {
      throw new Error(createResponse.message)
    }

    currentModelId.value = createResponse.data.id
    addLog('info', `模型创建成功，ID: ${currentModelId.value}`)

    // 开始训练
    addLog('info', '开始训练模型...')
    addLog('info', `模型类型: ${trainingConfig.modelType}`)
    addLog('info', `算法: ${trainingConfig.algorithm}`)
    addLog('info', `数据集: ${trainingConfig.dataset}`)

    const trainingResponse = await startModelTraining(currentModelId.value)
    if (!trainingResponse.success) {
      throw new Error(trainingResponse.message)
    }

    addLog('info', '训练已启动，开始监控进度...')

    // 开始轮询训练状态
    startStatusPolling()

    ElMessage.success('模型训练已开始')
  } catch (error) {
    isTraining.value = false
    ElMessage.error(error.message || '训练启动失败')
    addLog('error', `训练启动失败: ${error.message}`)
  }
}

const stopTraining = async () => {
  try {
    if (currentModelId.value) {
      await stopModelTraining(currentModelId.value)
    }

    if (statusCheckInterval.value) {
      clearInterval(statusCheckInterval.value)
      statusCheckInterval.value = null
    }

    isTraining.value = false
    addLog('warning', '训练已停止')
    ElMessage.warning('训练已停止')
  } catch (error) {
    ElMessage.error('停止训练失败')
  }
}

// 开始状态轮询
const startStatusPolling = () => {
  statusCheckInterval.value = setInterval(async () => {
    try {
      const response = await getTrainingStatus(currentModelId.value)
      if (response.success) {
        const status = response.data

        // 更新训练状态
        if (status.status === 'completed') {
          completeTraining(status)
        } else if (status.status === 'failed') {
          failTraining(status)
        } else {
          updateTrainingProgress(status)
        }
      }
    } catch (error) {
      console.error('获取训练状态失败:', error)
    }
  }, 2000) // 每2秒检查一次
}

// 更新训练进度
const updateTrainingProgress = (status) => {
  // 更新基础进度
  if (status.progress !== undefined) {
    currentEpoch.value = Math.floor(status.progress)
  }

  // 解析训练消息，提取详细信息
  if (status.message) {
    const message = status.message
    currentOperation.value = message

    // 解析不同的训练阶段
    if (message.includes('准备数据')) {
      trainingPhase.value = '数据准备'
      currentStep.value = '加载和预处理训练数据...'
    } else if (message.includes('特征工程')) {
      trainingPhase.value = '特征工程'
      currentStep.value = '生成和选择最优特征...'
    } else if (message.includes('超参数调优')) {
      trainingPhase.value = '超参数调优'

      // 提取调优信息
      const iterMatch = message.match(/(\d+)\/(\d+)/)
      if (iterMatch) {
        tuningIteration.value = parseInt(iterMatch[1])
        maxTuningIterations.value = parseInt(iterMatch[2])
        currentStep.value = `正在测试第 ${iterMatch[1]} 组参数，共 ${iterMatch[2]} 组`
      }

      // 提取F1分数
      const f1Match = message.match(/F1[:\s]*([0-9.]+)/)
      if (f1Match) {
        currentBestF1.value = parseFloat(f1Match[1]).toFixed(4)
      }
    } else if (message.includes('模型训练')) {
      trainingPhase.value = '模型训练'
      currentStep.value = '使用最优参数训练最终模型...'
    } else if (message.includes('模型评估')) {
      trainingPhase.value = '模型评估'
      currentStep.value = '评估模型性能和生成报告...'
    } else if (message.includes('保存模型')) {
      trainingPhase.value = '保存模型'
      currentStep.value = '保存训练好的模型文件...'
    }

    addLog('info', message)
  }

  // 更新已用时间
  if (trainingStartTime.value) {
    const elapsed = Date.now() - trainingStartTime.value
    const minutes = Math.floor(elapsed / 60000)
    const seconds = Math.floor((elapsed % 60000) / 1000)
    elapsedTime.value = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`

    // 估算剩余时间（基于当前进度）
    if (currentEpoch.value > 0) {
      const totalEstimated = (elapsed / currentEpoch.value) * 100
      const remaining = totalEstimated - elapsed
      if (remaining > 0) {
        const remainingMinutes = Math.floor(remaining / 60000)
        const remainingSeconds = Math.floor((remaining % 60000) / 1000)
        estimatedTime.value = `${remainingMinutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
      } else {
        estimatedTime.value = '即将完成'
      }
    }
  }

  if (status.logs) {
    // 解析日志并添加到显示中
    const newLogs = status.logs.split('\n').filter(log => log.trim())
    newLogs.forEach(log => {
      if (log.includes('[') && log.includes('%]')) {
        addLog('info', log)
      }
    })
  }
}

// 完成训练
const completeTraining = (status) => {
  if (statusCheckInterval.value) {
    clearInterval(statusCheckInterval.value)
    statusCheckInterval.value = null
  }

  isTraining.value = false
  trainingResult.value = status.results || status.metrics

  addLog('success', '🎉 模型训练完成！')

  if (status.results) {
    const metrics = status.results
    Object.keys(metrics).forEach(key => {
      if (typeof metrics[key] === 'number') {
        addLog('info', `${key}: ${metrics[key].toFixed(4)}`)
      }
    })
  }

  // 显示详细的训练完成信息
  const accuracy = status.metrics?.accuracy || 0
  const f1Score = status.metrics?.f1_score || 0
  const qualityScore = status.quality_score || 0

  ElMessage.success({
    message: `模型训练完成！准确率: ${(accuracy * 100).toFixed(2)}%, F1分数: ${(f1Score * 100).toFixed(2)}%, 质量评分: ${qualityScore.toFixed(1)}/100`,
    duration: 5000
  })

  // 如果有改进建议，显示提示
  if (status.recommendations && status.recommendations.length > 0) {
    setTimeout(() => {
      ElMessage.info({
        message: `训练建议: ${status.recommendations[0]}`,
        duration: 8000
      })
    }, 2000)
  }
}

// 训练失败
const failTraining = (status) => {
  if (statusCheckInterval.value) {
    clearInterval(statusCheckInterval.value)
    statusCheckInterval.value = null
  }

  isTraining.value = false
  addLog('error', '❌ 模型训练失败')

  if (status.message) {
    addLog('error', status.message)
  }

  ElMessage.error('模型训练失败')
}

// 处理模型类型变化
const handleModelTypeChange = () => {
  // 清空相关选择
  trainingConfig.algorithm = ''
  trainingConfig.dataset = ''
  trainingConfig.training_params = {}

  // 更新可用算法
  if (trainingConfig.modelType && algorithmConfigs[trainingConfig.modelType]) {
    availableAlgorithms.value = algorithmConfigs[trainingConfig.modelType]
  } else {
    availableAlgorithms.value = []
  }

  // 更新可用数据集
  if (trainingConfig.modelType && datasetConfigs[trainingConfig.modelType]) {
    availableDatasets.value = datasetConfigs[trainingConfig.modelType]
  } else {
    availableDatasets.value = []
  }
}

// 处理算法变化
const handleAlgorithmChange = () => {
  // 根据算法设置默认参数
  trainingConfig.training_params = getDefaultParams(trainingConfig.modelType, trainingConfig.algorithm)
}

// 获取优化的默认参数
const getDefaultParams = (modelType, algorithm) => {
  const defaultParams = {
    'xgboost': {
      n_estimators: 200,  // 增加树的数量
      max_depth: 8,  // 增加深度
      learning_rate: 0.1,
      subsample: 0.8,
      colsample_bytree: 0.8,
      gamma: 0.1,  // 添加正则化
      reg_alpha: 0.1,
      reg_lambda: 1.0,
      min_child_weight: 3,
      scale_pos_weight: 1,
      random_state: 42
    },
    'random_forest': {
      n_estimators: 200,  // 增加树的数量
      max_depth: 15,  // 增加深度
      min_samples_split: 5,
      min_samples_leaf: 2,
      max_features: 'sqrt',
      bootstrap: true,
      class_weight: 'balanced',  // 处理类别不平衡
      random_state: 42
    },
    'logistic_regression': {
      C: 10.0,  // 增加正则化强度
      penalty: 'l2',
      solver: 'lbfgs',
      class_weight: 'balanced',  // 处理类别不平衡
      max_iter: 2000,  // 增加迭代次数
      random_state: 42
    },
    'neural_network': {
      hidden_layer_sizes: [200, 100, 50],  // 增加网络复杂度
      activation: 'relu',
      solver: 'adam',
      alpha: 0.001,  // 增加正则化
      learning_rate_init: 0.01,
      max_iter: 1000,  // 增加迭代次数
      early_stopping: true,  // 启用早停
      validation_fraction: 0.1,
      random_state: 42
    },
    'collaborative_filtering': {
      k: 40,
      sim_options: {
        name: 'cosine',
        user_based: true
      }
    },
    'matrix_factorization': {
      n_factors: 50,
      n_epochs: 20,
      lr_all: 0.005,
      reg_all: 0.02
    },
    'content_based': {
      similarity_metric: 'cosine',
      n_recommendations: 10
    },
    'kmeans': {
      n_clusters: 5,
      init: 'k-means++',
      n_init: 10,
      max_iter: 300
    },
    'dbscan': {
      eps: 0.5,
      min_samples: 5
    },
    'hierarchical': {
      n_clusters: 5,
      linkage: 'ward'
    }
  }

  return defaultParams[algorithm] || {}
}

// 辅助函数
const getComplexityType = (complexity) => {
  const typeMap = {
    'low': 'success',
    'medium': 'warning',
    'high': 'danger'
  }
  return typeMap[complexity] || 'info'
}

const getComplexityLabel = (complexity) => {
  const labelMap = {
    'low': '简单',
    'medium': '中等',
    'high': '复杂'
  }
  return labelMap[complexity] || '未知'
}

const simulateTrainingStep = () => {
  currentEpoch.value++
  
  // 模拟指标变化
  const loss = Math.max(0.001, 2 * Math.exp(-currentEpoch.value / 20) + Math.random() * 0.1)
  const accuracy = Math.min(0.99, 0.5 + 0.4 * (1 - Math.exp(-currentEpoch.value / 30)) + Math.random() * 0.05)
  const valLoss = loss + Math.random() * 0.05
  const valAccuracy = accuracy - Math.random() * 0.05
  
  currentMetrics.value[0].value = loss.toFixed(4)
  currentMetrics.value[1].value = (accuracy * 100).toFixed(2) + '%'
  currentMetrics.value[2].value = valLoss.toFixed(4)
  currentMetrics.value[3].value = (valAccuracy * 100).toFixed(2) + '%'
  
  // 添加到历史记录
  trainingHistory.value.push({
    epoch: currentEpoch.value,
    loss: loss,
    accuracy: accuracy,
    valLoss: valLoss,
    valAccuracy: valAccuracy
  })
  
  // 更新图表
  updateCharts()
  
  // 添加日志
  if (currentEpoch.value % 10 === 0) {
    addLog('info', `Epoch ${currentEpoch.value}/${trainingConfig.epochs} - loss: ${loss.toFixed(4)} - accuracy: ${(accuracy * 100).toFixed(2)}%`)
  }

  // 检查是否完成
  if (currentEpoch.value >= trainingConfig.epochs) {
    // 模拟训练完成状态
    const mockStatus = {
      results: {
        accuracy: trainingHistory.value[trainingHistory.value.length - 1]?.accuracy || 0.85,
        loss: trainingHistory.value[trainingHistory.value.length - 1]?.loss || 0.15
      }
    }
    completeTraining(mockStatus)
  }
}



const addLog = (type, message) => {
  trainingLogs.value.push({
    type,
    message,
    timestamp: new Date().toLocaleTimeString()
  })
  
  // 限制日志数量
  if (trainingLogs.value.length > 100) {
    trainingLogs.value.shift()
  }
}

const clearLogs = () => {
  trainingLogs.value = []
}

const getLogClass = (type) => {
  return `log-${type}`
}

const updateCharts = () => {
  nextTick(() => {
    renderLossChart()
    renderAccuracyChart()
  })
}

const renderLossChart = () => {
  if (!lossChartRef.value || trainingHistory.value.length === 0) return

  const chart = echarts.init(lossChartRef.value)
  
  const epochs = trainingHistory.value.map(h => h.epoch)
  const trainLoss = trainingHistory.value.map(h => h.loss)
  const valLoss = trainingHistory.value.map(h => h.valLoss)
  
  const option = {
    title: {
      text: '损失曲线',
      left: 'center',
      textStyle: { fontSize: 14 }
    },
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: ['训练损失', '验证损失'],
      top: 30
    },
    xAxis: {
      type: 'category',
      data: epochs,
      name: 'Epoch'
    },
    yAxis: {
      type: 'value',
      name: 'Loss'
    },
    series: [
      {
        name: '训练损失',
        type: 'line',
        data: trainLoss,
        smooth: true,
        itemStyle: { color: '#409EFF' }
      },
      {
        name: '验证损失',
        type: 'line',
        data: valLoss,
        smooth: true,
        itemStyle: { color: '#F56C6C' }
      }
    ]
  }

  chart.setOption(option)
}

const renderAccuracyChart = () => {
  if (!accuracyChartRef.value || trainingHistory.value.length === 0) return

  const chart = echarts.init(accuracyChartRef.value)
  
  const epochs = trainingHistory.value.map(h => h.epoch)
  const trainAcc = trainingHistory.value.map(h => h.accuracy * 100)
  const valAcc = trainingHistory.value.map(h => h.valAccuracy * 100)
  
  const option = {
    title: {
      text: '准确率曲线',
      left: 'center',
      textStyle: { fontSize: 14 }
    },
    tooltip: {
      trigger: 'axis',
      formatter: function(params) {
        let result = `Epoch ${params[0].axisValue}<br/>`
        params.forEach(param => {
          result += `${param.seriesName}: ${param.value.toFixed(2)}%<br/>`
        })
        return result
      }
    },
    legend: {
      data: ['训练准确率', '验证准确率'],
      top: 30
    },
    xAxis: {
      type: 'category',
      data: epochs,
      name: 'Epoch'
    },
    yAxis: {
      type: 'value',
      name: 'Accuracy (%)',
      min: 0,
      max: 100
    },
    series: [
      {
        name: '训练准确率',
        type: 'line',
        data: trainAcc,
        smooth: true,
        itemStyle: { color: '#67C23A' }
      },
      {
        name: '验证准确率',
        type: 'line',
        data: valAcc,
        smooth: true,
        itemStyle: { color: '#E6A23C' }
      }
    ]
  }

  chart.setOption(option)
}

const viewModel = () => {
  router.push('/models/browser')
}

const evaluateModel = () => {
  router.push('/models/evaluate')
}

const resetTraining = () => {
  trainingResult.value = null
  trainingHistory.value = []
  trainingLogs.value = []
  currentEpoch.value = 0
}

// 生命周期
onMounted(() => {
  // 如果URL中有模型ID，加载模型配置
  const modelId = route.params.id
  if (modelId) {
    // 加载现有模型配置
    trainingConfig.modelName = `模型_${modelId}_重训练`
  }

  nextTick(() => {
    initCharts()
  })
})

onUnmounted(() => {
  if (statusCheckInterval.value) {
    clearInterval(statusCheckInterval.value)
  }

  // 销毁图表
  if (lossChart) {
    lossChart.dispose()
  }
  if (accuracyChart) {
    accuracyChart.dispose()
  }
})
</script>

<style scoped>
.model-training {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 120px);
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header-content h1 {
  margin: 0 0 8px 0;
  font-size: 24px;
  color: #303133;
}

.header-content p {
  margin: 0;
  color: #606266;
  font-size: 14px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.training-config,
.training-progress,
.training-logs,
.training-result {
  margin-bottom: 20px;
}

.current-training {
  margin-bottom: 20px;
}

.progress-info {
  margin-bottom: 20px;
}

.progress-stats {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
}

.stat-item {
  font-size: 14px;
}

.label {
  color: #909399;
}

.value {
  color: #303133;
  font-weight: 500;
}

.training-metrics {
  margin-bottom: 20px;
}

.metric-card {
  text-align: center;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
}

.metric-label {
  font-size: 12px;
  color: #909399;
  margin-bottom: 8px;
}

.metric-value {
  font-size: 20px;
  font-weight: bold;
  color: #303133;
}

.training-charts {
  margin-top: 20px;
}

.chart-container {
  height: 300px;
  width: 100%;
}

.logs-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.logs-container {
  max-height: 300px;
  overflow-y: auto;
  font-family: 'Monaco', monospace;
  font-size: 12px;
}

.log-item {
  padding: 4px 8px;
  border-left: 3px solid transparent;
  margin-bottom: 2px;
}

.log-info {
  border-left-color: #409EFF;
  background: rgba(64, 158, 255, 0.1);
}

.log-success {
  border-left-color: #67C23A;
  background: rgba(103, 194, 58, 0.1);
}

.log-warning {
  border-left-color: #E6A23C;
  background: rgba(230, 162, 60, 0.1);
}

.log-error {
  border-left-color: #F56C6C;
  background: rgba(245, 108, 108, 0.1);
}

.log-time {
  color: #909399;
  margin-right: 8px;
}

.log-message {
  color: #303133;
}

.final-metrics {
  margin-top: 20px;
}

.final-metrics h4 {
  margin: 0 0 16px 0;
  color: #303133;
}

/* 新增的训练进度样式 */
.current-operation {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 16px 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.operation-info {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 16px;
  font-weight: 600;
}

.operation-info .el-icon {
  font-size: 20px;
}

.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.operation-details {
  margin-top: 8px;
  font-size: 14px;
  opacity: 0.9;
}

.progress-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: #f8f9fa;
  border-radius: 6px;
  border-left: 4px solid #409EFF;
}

.stat-item .label {
  font-size: 13px;
  color: #606266;
  font-weight: 500;
}

.stat-item .value {
  font-size: 14px;
  color: #303133;
  font-weight: 600;
}

/* 进度条样式增强 */
.progress-info .el-progress {
  margin-top: 16px;
}

.progress-info .el-progress__text {
  font-weight: 600;
  color: #409EFF;
}

@media (max-width: 768px) {
  .progress-stats {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .current-operation {
    padding: 12px 16px;
  }

  .operation-info {
    font-size: 14px;
  }
}
</style>
